From 992e40835af1600a0961ec2454fb78ff43aec3c6 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Mon, 7 Sep 2026 22:31:23 +0200 Subject: Add routine archives: archive date, searchable archived list, frozen page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Stamp archived_at on the archived snapshot; copy it on edit - loadArchived(projectId) + collapsible fuzzy-searched "Archivées" section on the project page - Archived routine pages open read-only with the health chart ending at the archive date; edit/complete actions reject archived routines --- .../routine/[routineId]/+page.server.ts | 21 ++- .../[projectId]/routine/[routineId]/+page.svelte | 186 ++++++++++++--------- 2 files changed, 125 insertions(+), 82 deletions(-) (limited to 'src/routes/projects/[projectId]') diff --git a/src/routes/projects/[projectId]/routine/[routineId]/+page.server.ts b/src/routes/projects/[projectId]/routine/[routineId]/+page.server.ts index 83bac3c..f2b6551 100644 --- a/src/routes/projects/[projectId]/routine/[routineId]/+page.server.ts +++ b/src/routes/projects/[projectId]/routine/[routineId]/+page.server.ts @@ -31,21 +31,31 @@ export const load: PageServerLoad = async ({ params }) => { } const routine = await loadCurrent(routineId); - if (!routine || routine.archived || routine.projectId !== projectId) { + if (!routine || routine.projectId !== projectId) { throw error(404, 'Routine introuvable'); } const completions = await loadCompletions(routineId); + // An archived routine is frozen at its archive instant: state and chart + // stop there instead of now. + const at = routine.archivedAt ? Date.parse(routine.archivedAt) : Date.now(); return { project: { id: project.id, name: project.name }, routine, completions, - state: computeRoutineState(routine, completions, Date.now()), + state: computeRoutineState(routine, completions, at), }; }; export const actions: Actions = { edit: async ({ request, params }) => { + const current = await loadCurrent(numericId(params.routineId)); + if (!current) { + return fail(400, { error: 'Routine introuvable' }); + } + if (current.archived) { + return fail(400, { error: 'Routine archivée' }); + } const data = await request.formData(); const name = parseFormString(data.get('name')); if (!name) { @@ -65,6 +75,13 @@ export const actions: Actions = { }, complete: async ({ request, params }) => { + const current = await loadCurrent(numericId(params.routineId)); + if (!current) { + return fail(400, { error: 'Routine introuvable' }); + } + if (current.archived) { + return fail(400, { error: 'Routine archivée' }); + } const data = await request.formData(); try { await complete( diff --git a/src/routes/projects/[projectId]/routine/[routineId]/+page.svelte b/src/routes/projects/[projectId]/routine/[routineId]/+page.svelte index d57ed79..5f57de4 100644 --- a/src/routes/projects/[projectId]/routine/[routineId]/+page.svelte +++ b/src/routes/projects/[projectId]/routine/[routineId]/+page.svelte @@ -42,8 +42,14 @@ year: 'numeric', }); + const frozenAt = $derived( + data.routine.archived + ? Date.parse(data.routine.archivedAt ?? data.routine.createdAt) + : Date.now(), + ); + const series = $derived( - computeHealthSeries(data.routine, data.completions, Date.now()), + computeHealthSeries(data.routine, data.completions, frozenAt), ); const PAD = 10; @@ -93,65 +99,76 @@ {data.state.health} -
{ - return async ({ result, update }) => { - await update({ reset: false }); - }; - }} - > - {#if form?.error} -

{form.error}

- {/if} - - - - {#if frequency !== '' && frequencyDays === null} -

Intervalle invalide — ex : 1d, 2w, 3m, 1y

- {/if} - -

✓ Enregistré

-
+ {#if form?.error} +

{form.error}

+ {/if} + + + + {#if frequency !== '' && frequencyDays === null} +

Intervalle invalide — ex : 1d, 2w, 3m, 1y

+ {/if} + +

✓ Enregistré

+ + {/if}

Santé

@@ -197,27 +214,29 @@

Historique

-
{ - return async ({ update }) => { - note = ''; - await update({ reset: false }); - }; - }} - > - - -
+ {#if !data.routine.archived} +
{ + return async ({ update }) => { + note = ''; + await update({ reset: false }); + }; + }} + > + + +
+ {/if}